#ifndef _BACKGROUND_H_
#define _BACKGROUND_H_

/*
 *  background.h
 *  
 *
 *  Created by Jason Hsu, Jian Wei Gan, and Weiping Zhang on 12/1/09.
 *  Copyright 2009. All rights reserved.
 *
 */

#include "rain.h"
#include "texture.h"
#include "terrain.h"
#include "sky.h"
#include "tree2.h"

#include "util/vec3f.h"
#include "util/color4f.h"
#include "weather/weatherparser.h"

#include <vector>

#define NUMBER_RAIN_COLUMNS 800
#define AMBIENT_RAIN_DROPS_PER_FRAME 200

class Background
{
private:
    weather_t *myWeather;
	Terrain* myTerrain;
	Sky* mySky;
	
	list<Tree2*>* myTreeList;
	GLint myNumTrees;
	
    Rain *myRain;
    Vec3f myRainCenter;
    Vec3f myRainArea;
	
public:
    Background(weather_t *weather)
	{
        myWeather = weather;
	    
		//############################# Terrain
		Image* heightmap = loadBMP("heightmap3.bmp");	//reads in heightmap from grayscale bitmap image file
		myTerrain = new Terrain(heightmap->width, heightmap->height, heightmap);	//create terrain
		delete heightmap;
		
		//############################# Sky
		mySky = new Sky(weather);
		
		//############################# Trees
		myNumTrees = 7;
		myTreeList = new list<Tree2*> ();
		for(GLint k = 0; k<myNumTrees; k++)
		{
			GLfloat x = 40.0f + 2.0f*k;
			GLfloat z = 30.0f + randFloatRange(-3.0f, 3.0f);
			Tree2* tree = new Tree2();
			
			tree->setPosition((x-29.0f)*(160.0f/60.0f), myTerrain->getHeight(x, z), z-59.0f);
			tree->scale();
			myTreeList->push_back(tree);
		}
		
        myRainCenter = Vec3f(0.0, 20.0, -25.0f);
        myRainArea = Vec3f(120.0, 0.0, 50.0);
        myRain = new Rain(AMBIENT_RAIN_DROPS_PER_FRAME, myRainCenter, myRainArea);
	}
	
	~Background()
	{
		delete myTerrain;
		delete mySky;
		for(GLint k = 0; k<myNumTrees; k++)
		{
			myTreeList->pop_back();
		}
		delete myTreeList;
        delete myRain;
	}
	
	void draw()
	{
		myTerrain->draw();
		mySky->draw();
		list<Tree2*>::iterator iter;
		for(iter = myTreeList->begin(); iter != myTreeList->end(); iter++)
		{
			(*iter)->draw();
		}
		if (*myWeather == RAINY) 
		{
            myRain->draw();
        }
	}
	
	void update()
	{
		myTerrain->update();
		mySky->update();
		list<Tree2*>::iterator iter;
		for(iter = myTreeList->begin(); iter != myTreeList->end(); iter++)
		{
			(*iter)->update();
		}
		if (*myWeather == RAINY) 
		{
            myRain->update();
        }
	}
	
	Terrain* getTerrain()
	{
		return myTerrain;
	}
};
#endif
